package org.kabanyo.components {
	import mx.core.IFactory;

	import org.kabanyo.components.supportClasses.CircularSeriesRenderer;
	import org.kabanyo.skins.CircularDataContainerSkin;
	import org.kabanyo.utils.DataSeriesUtil;

	import spark.components.SkinnableContainer;

	/**
	 * Display data series in circular curve chart.
	 *
	 * @author Desky Natalio
	 *
	 */
	public class CircularDataContainer extends SkinnableContainer {

		//Skin Part
		/**
		 *  @private
		 *  IFactory valued skin parts that require special handling, see findSkinParts().
		 */
		private static const factorySkinPartNames:Array=["circularSeriesRenderer"];

		[SkinPart(required="false", type="mx.core.IVisualElement")]
		public var circularSeriesRenderer:IFactory;

		private var _dataSeries:IDataSeries;

		[Bindable]
		/**
		 * Generate series from data provider.
		 */
		public function get dataSeries():IDataSeries {
			return _dataSeries;
		}

		/**
		 * @private
		 */
		public function set dataSeries(value:IDataSeries):void {
			_dataSeries=value;
			invalidateDataList();
		}

		private var _centerX:Number;

		[Bindable]
		/**
		 * x Center of Circular arc.
		 */
		public function get centerX():Number {
			return _centerX;
		}

		/**
		 * @private
		 */
		public function set centerX(value:Number):void {
			_centerX=value;
		}

		private var _centerY:Number;

		[Bindable]
		/**
		 * y Center of Circular arc.
		 */
		public function get centerY():Number {
			return _centerY;
		}

		/**
		 * @private
		 */
		public function set centerY(value:Number):void {
			_centerY=value;
		}

		private var _innerRadius:Number;

		[Bindable]
		/**
		 * inner radius of Circular arc.
		 */
		public function get innerRadius():Number {
			return _innerRadius;
		}

		/**
		 * @private
		 */
		public function set innerRadius(value:Number):void {
			_innerRadius=value;
		}

		private var _arcThick:Number;

		[Bindable]
		/**
		 * arc thickness of Circular arc.
		 */
		public function get arcThick():Number {
			return _arcThick;
		}

		/**
		 * @private
		 */
		public function set arcThick(value:Number):void {
			_arcThick=value;
		}

		private var _colors:Array;

		[Bindable]
		/**
		 * Set of color indicator of group field.
		 */
		[ArrayElementType("uint")]
		public function get colors():Array {
			return _colors;
		}

		/**
		 * @private
		 */
		public function set colors(value:Array):void {
			_colors=value;
		}

		private var _unit:String;

		[Bindable]
		/**
		 * The unit of data.
		 */
		public function get unit():String {
			return _unit;
		}

		/**
		 * @private
		 */
		public function set unit(value:String):void {
			_unit=value;
		}

		/**
		 * Constructor
		 */
		public function CircularDataContainer() {
			super();
			setStyle("skinClass", CircularDataContainerSkin);
		}

		/**
		 *  @private
		 *  Call partAdded() for IFactory type skin parts.   By default, partAdded() is not
		 *  called for IFactory type skin part variables, because they're assumed to be
		 *  "dynamic" skin parts, to be created with createDynamicPartInstance().  That's
		 *  not the case with the IFactory valued parts listed in factorySkinPartNames.
		 */
		override protected function findSkinParts():void {
			super.findSkinParts();

			for each (var partName:String in factorySkinPartNames) {
				if ((partName in skin) && skin[partName]) {
					partAdded(partName, skin[partName]);
				}
			}
		}

		protected function invalidateDataList():void {
			if (!dataSeries) {
				return;
			}
			var seriesNames:Array=dataSeries.getSeriesNames();
			for (var i:int=0; i < seriesNames.length; i++) {
				var seriesItem:ISeriesItem=dataSeries.getSeriesItem(seriesNames[i], unit);
				if (seriesItem) {
					var values:Array=seriesItem.values;
					var total:Number=DataSeriesUtil.sum(values, "value");
					var startAngle:Number=-90;
					for (var j:int=0; j < values.length; j++) {
						var seriesRenderer:CircularSeriesRenderer=circularSeriesRenderer.newInstance();
						seriesRenderer.label=seriesItem.name;
						seriesRenderer.unit=seriesItem.unit;
						seriesRenderer.data=values[i]["value"];
						seriesRenderer.color=colors[i];
						seriesRenderer.centerX=centerX;
						seriesRenderer.centerY=centerY;
						seriesRenderer.innerRadius=innerRadius;
						seriesRenderer.arcThick=arcThick * i;
						seriesRenderer.startAngle=startAngle;
						seriesRenderer.endAngle=startAngle + ((values[i]["value"] / total) * 360);
						contentGroup.addElement(seriesRenderer);
						startAngle=startAngle + ((values[i]["value"] / total) * 360);
					}
				}
			}
		}
	}
}
